package com.nameless.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nameless.dao.ClientMapper;
import com.nameless.dao.CouponHistoryMapper;
import com.nameless.dao.CouponMapper;
import com.nameless.entity.Car;
import com.nameless.entity.Client;
import com.nameless.entity.Coupon;
import com.nameless.entity.CouponHistory;
import com.nameless.service.CouponHistoryService;
import com.nameless.util.JwtUtil;
import com.nameless.util.WebUtils;
import com.nameless.vo.CouponHistoryVo;
import com.nameless.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.util.calendar.LocalGregorianCalendar;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * -*- coding:utf-8 -*-
 *
 * @author 太阳偷渡青山
 * @software IntelliJ IDEA
 * @date 2023/02/27 9:47
 * @Description
 */
@Service
@Slf4j
public class CouponHistoryServiceImpl extends ServiceImpl<CouponHistoryMapper, CouponHistory> implements CouponHistoryService {

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private ClientMapper clientMapper;

    @Override
    public Page<CouponHistory> pageByNames(Integer pageNo, Integer pageSize, CouponHistory history) {

        // 构造一个分页器，传递当前页与每页的页数
        Page<CouponHistory> setPage = new Page<>(pageNo, pageSize);

        // 查询该优惠劵对应的id集合
        LambdaQueryWrapper<Coupon> couponWrapper = new LambdaQueryWrapper<>();
        couponWrapper.like(StringUtils.isNotEmpty(history.getCouponName()),Coupon::getName,history.getCouponName());

        List<Coupon> coupons = couponMapper.selectList(couponWrapper);
        List<Long> couponsIds = coupons.stream().map(Coupon::getId).collect(Collectors.toList());

        // 查询该客户名对应的id集合
        LambdaQueryWrapper<Client> customerWrapper = new LambdaQueryWrapper<>();
        customerWrapper.like(StringUtils.isNotEmpty(history.getClientName()),Client::getName,history.getClientName());

        List<Client> customer = clientMapper.selectList(customerWrapper);
        List<Integer> customerIds =customer.stream().map(Client::getId).collect(Collectors.toList());

        LambdaQueryWrapper<CouponHistory> wrapper = new LambdaQueryWrapper<>();

        wrapper.in(CouponHistory::getCouponId,couponsIds);
        wrapper.in(CouponHistory::getClientId,customerIds);

        Page<CouponHistory> page = baseMapper.selectPage(setPage, wrapper);

        List<CouponHistory> collect = page.getRecords().stream().peek(this::addCouponAndClient).collect(Collectors.toList());

        page.setRecords(collect);

        log.info("{}",collect);

        return page;
    }

    @Override
    public List<CouponHistory> list(Wrapper<CouponHistory> queryWrapper) {
        List<CouponHistory> couponHistoryList = baseMapper.selectList(queryWrapper);
        return couponHistoryList.stream().peek(this::addCouponAndClient).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public Result<String> toReceiveCoupon(Long couponId) {
        CouponHistory couponHistory = new CouponHistory();

        Client client = getTokenClient();

        couponHistory.setClientId(client.getId());

        // 查询当前优惠劵
        Coupon coupon = couponMapper.selectById(couponId);
        LambdaQueryWrapper<CouponHistory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CouponHistory::getClientId,client.getId());
        queryWrapper.eq(CouponHistory::getCouponId,couponId);
        Long aLong = baseMapper.selectCount(queryWrapper);
        if (aLong >= coupon.getPerLimit()){
            return Result.error("每人限领优惠劵"+coupon.getPerLimit() +"张");
        }
        if (coupon.getPublishCount() > 0) {
            couponHistory.setCouponId(couponId);
            couponHistory.setCouponName(coupon.getName());
            couponHistory.setCreateTime(new Date());
            couponHistory.setGetType(1);
            couponHistory.setUseStatus(1);
            couponHistory.setCouponCode(coupon.getCode());

            baseMapper.insert(couponHistory);
        }else {
            return Result.error("优惠劵数量不足");
        }
        // 领取掉一张优惠劵
        coupon.setPublishCount(coupon.getPublishCount() - 1);
        coupon.setReceiveCount(coupon.getReceiveCount() + 1);
        couponMapper.updateById(coupon);
        return Result.success("领取成功");
    }

    @Override
    @Transactional
    public Result<String> saveBycouponHistoryVo(CouponHistoryVo couponHistoryVo) {

        couponHistoryVo.getCouponId().stream().map(item ->{

            CouponHistory couponHistory = new CouponHistory();
            // 查询当前优惠劵
            Coupon coupon = couponMapper.selectById(item);

            if (coupon.getPublishCount() > 0) {

                couponHistory.setClientId(couponHistoryVo.getClientId());
                couponHistory.setCouponId(item);
                couponHistory.setCouponName(coupon.getName());
                couponHistory.setCreateTime(new Date());
                couponHistory.setGetType(0);
                couponHistory.setUseStatus(1);
                couponHistory.setCouponCode(coupon.getCode());

                baseMapper.insert(couponHistory);
            }else {
                return Result.error("优惠劵数量不足");
            }
            // 使用掉一张优惠劵
            coupon.setPublishCount(coupon.getPublishCount() - 1);
            couponMapper.updateById(coupon);
            return null;
        }).collect(Collectors.toList());
        return null;
    }

    @Override
    @Transactional
    public Result<String> useCoupon(Long couponId, String orderSn) {
        Client client = getTokenClient();
        LambdaQueryWrapper<CouponHistory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CouponHistory::getCouponId,couponId);
        queryWrapper.eq(CouponHistory::getClientId,client.getId());
        CouponHistory couponHistory = baseMapper.selectOne(queryWrapper);
        couponHistory.setUseStatus(0);
        couponHistory.setUseTime(new Date());
        couponHistory.setOrderSn(orderSn);
        int i = baseMapper.updateById(couponHistory);

        // 优惠劵修改使用掉的数量
        Coupon coupon = couponMapper.selectById(couponId);
        coupon.setUseCount(coupon.getUseCount() + 1);
        couponMapper.updateById(coupon);

        return i>0?Result.success("修改成功"):Result.error("修改失败");
    }

    @Override
    public Map<String, List<Coupon>> getCouponByClientId(Car car) {
        Client client = getTokenClient();
        LambdaQueryWrapper<CouponHistory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CouponHistory::getClientId,client.getId());
        queryWrapper.eq(CouponHistory::getUseStatus,1);
        // 获取到该用户所有拥有且未使用的优惠劵记录
        List<CouponHistory> couponHistoryList = baseMapper.selectList(queryWrapper);

        log.info("couponId = {}");

        Map<String, List<Coupon>> map = new HashMap<>(2);
        List<Coupon> coupons = new ArrayList<>();
        List<Coupon> disabledCoupons = new ArrayList<>();

        couponHistoryList.stream().map(item -> {
            Long couponId = item.getCouponId();
            log.info("couponId = {}",couponId);
            Coupon coupon = couponMapper.selectById(couponId);

            // 进行优惠劵消息转换
            if (coupon.getDenominations() != null){
                coupon.setDenominations(coupon.getDenominations().multiply(new BigDecimal("100")));
            }
            if (coupon.getOriginCondition() != null){
                coupon.setOriginCondition(coupon.getOriginCondition().multiply(new BigDecimal("100")));
            }
            if (coupon.getValue() != null){
                coupon.setValue(coupon.getValue().multiply(new BigDecimal("100")));
            }
            coupon.setStartAt(coupon.getStartTime().getTime() / 1000L);
            coupon.setEndAt(coupon.getEndTime().getTime() / 1000L);

            log.info("coupon = {}",coupon);
            // 判断优惠劵是否过期
            if (coupon.getEndTime().before(new Date())){
                coupon.setReason("优惠劵已过期");
                disabledCoupons.add(coupon);
            }// 判断该车是否可以使用该优惠劵
            else if (coupon.getUseType() == 0){
                coupons.add(coupon);
            }else if(coupon.getUseType() == 1){
                List<String> list = Arrays.asList(coupon.getTypeId().split(","));
                boolean b = list.stream().anyMatch(id -> id.equals(car.getType().toString()));
                if (b) {
                    coupons.add(coupon);
                } else {
                    disabledCoupons.add(coupon);
                }
            }else if(coupon.getUseType() == 2) {
                List<String> list = Arrays.asList(coupon.getCarId().split(","));
                boolean b = list.stream().anyMatch(id -> id.equals(car.getId().toString()));
                if (b) {
                    coupons.add(coupon);
                } else {
                    disabledCoupons.add(coupon);
                }
            }
            return null;
        }).collect(Collectors.toList());

        map.put("coupons",coupons);
        map.put("disabledCoupons",disabledCoupons);
        return map;
    }

    private void addCouponAndClient(CouponHistory item){
        if (item.getCouponId() != null && item.getCouponId() > 0){
            item.setCoupon(couponMapper.selectById(item.getCouponId()));
            item.setCouponName(couponMapper.selectById(item.getCouponId()).getName());
        }
        if (item.getClientId() != null && item.getClientId() > 0){
            item.setClientName(clientMapper.selectById(item.getClientId()).getName());
        }
    }



    private Client getTokenClient(){
        // 获取token值,获取用户id
        String token = WebUtils.getRequest().getHeader("token");
        Map<String, Object> tokenChaim = JwtUtil.getTokenChaim(token);
        String username = (String) tokenChaim.get("clientname");
        LambdaQueryWrapper<Client> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Client::getUsername,username);
        return clientMapper.selectOne(queryWrapper);
    }
}
